import { Model } from "./Model";
import * as fs from 'fs'
import * as crypto from 'crypto'
import * as path from 'path'
import {Relation} from './Relation'
import * as _ from 'lodash'
import {IServers} from '../interface/IFace'
import xtpl from './Template/Xtpl'

/**
 * 实例化数据库操作类
 * @param Table 
 * @param config 
 */
export function M(Table:string,config:IServers):Model {
    const Models={};
    if(!_.isObject(Models[Table])){
        try{
            var m = require(`${config.root}/Model/${Table}Model.js`)
            if(m){
                Models[Table] = new m[Table+'Model'](Table,config);
            }else{
                Models[Table] = new Model(Table,config)   
            }
        }catch(e){
            Models[Table] = new Model(Table,config)   
        }
    }
    return Models[Table];
}
/**
 * 实例化Relation方法
 * @param name 
 * @param config 
 */
export function R(name:string,config:IServers):Relation {    
    const Relations={};
    if(!_.isObject(Relations[name])){
        try{
            var r = require(config.root+`/Relation/${name}Relation.js`);
            if(r){
                Relations[name]=new r[name+'Relation'](name,get_table_fields(name,config),get_table_pk(name,config),config);
            }else{
                Relations[name]=new Relation(name,get_table_fields(name,config),get_table_pk(name,config),config);
            }
        }catch (e){
            Relations[name]=new Relation(name,get_table_fields(name,config),get_table_pk(name,config),config);
        }
    }
    return Relations[name];
}
 /**
* 密码加密
* @param pwd
* @returns {string}
*/
export function password_hash (pwd):string {
   const md5 = crypto.createHash('md5');
   return md5.update(pwd).digest('hex').toLowerCase();
}
/**
 * 密码验证
 * @param pwd
 * @param sign
 * @returns {boolean}
 */
export function password_verify (pwd,sign):boolean {
    const md5 = crypto.createHash('md5');
    return md5.update(pwd).digest('hex').toLowerCase()==sign;
}
/**
 * 遍历创建目录
 * @param dirpath 
 * @param mode 
 * @param callback 
 */
export function mkdirs(dirpath, mode=0o777, callback=null) {
    if(fs.existsSync(dirpath)){
        return true;
    }else{
        let parent_path = path.dirname(dirpath);
        if(fs.existsSync(parent_path)){
            return fs.mkdirSync(dirpath)
        }else{
            return mkdirs(parent_path)
        }
    }
};
/**
 * 仿造php的array_columns函数
 * @param arr
 * @param column
 * @returns {Array}
 */
export function array_columns(arr:Object|Array<Object>,column:string,unique=false){
    let a=[];
    _.forOwn(arr,(v:any,k)=>{
        if(unique){
            if(a.indexOf(v[column])==-1){
                a.push(v[column])
            }
        }else{
            a.push(v[column])
        }
    })
    return a;
}
/**
 * 取唯一值
 * @param arr
 */
export function array_unique(arr){
    return _.uniq(arr)
}
/**
 * 获取表定义
 * @param ModelName 
 * @param config 
 */
export function get_table_define(ModelName:string,config:IServers){
    var c ={};
    try{
        var s = require(config.root+`/Db/${ModelName}.js`)
        if(s){
            c=s[ModelName];
        }
    }catch (e){

    }finally {
        return c;
    }
}
/**
 * 获取表主键
 * @param ModelName 
 * @param config 
 */
export function get_table_pk(ModelName:string,config:IServers){
    var PK= 'ID';
    _.forOwn(get_table_define(ModelName,config),(v,k)=>{
        if(v.primaryKey===true){
            PK = k;
        }
    })
    return PK;
}
/**
 * 获取表字段信息
 * @param ModelName 
 * @param config 
 */
export function get_table_fields(ModelName:string,config:IServers){
    var Fields= [];
    _.forOwn(get_table_define(ModelName,config),(v,k)=>{
        Fields.push(k)
    })
    return Fields;
}
/**
 * 首字母大写
 * @param str 
 */
export function ucfirst(str:string):string{
    return str.charAt(0).toUpperCase()+str.slice(1)
}
/**
 * 字符串命名风格转换
 * @param str  字符串
 * @param type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 */
export function parse_name(str:string,type:boolean=false):string{
    if(type){
        return str.replace(/(_[a-z])/gm,(d)=>{return d.charAt(1).toUpperCase()})
    }else{
        return str.replace(/([A-Z])/gm,(d)=>{return '_'+d.charAt(0).toLowerCase()})
    }
}
/**
 * 渲染模板
 * @param TemplatePath 
 * @param Data 
 * @param RootDir 
 */
export function view_render(TemplatePath:string,Data:any,RootDir?:string):string{
    let content = ""
    if(!RootDir){
        RootDir = __dirname
    }
    xtpl.render(TemplatePath,Data,Object.assign({},{views:RootDir}),(e,data)=>{
        content=data;
    })
    return content;
}

// export 